package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.Movement;
import com.itheima.domain.vo.CommentVo;
import com.itheima.domain.vo.MovementVo;
import com.itheima.domain.vo.PageBeanVo;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.DateFormatUtil;
import io.netty.util.Constant;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class MovementManager {
    @DubboReference
    private MovementService movementService;

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private MQMovementManager mqMovementManager;
    /**
     * 发布动态
     * 1.完善movement对象的值
     * 2.用保存即可
     * @param movement
     * @param imageContent
     * @return
     */
    public ResponseEntity saveMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        //1.完善数据
        movement.setUserId(UserHolder.getUserId());  //发布人的id
        //定义url的集合
        List<String> pathList = new ArrayList<>();
        //2.处理图片 (如果图片存在 上传到阿里云)
        if(imageContent!=null &&imageContent.length>0){
            for (MultipartFile multipartFile : imageContent) {
                //获得文件上传之后的路径
                String uploadPath = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                pathList.add(uploadPath);
            }
        }

        //将数据存入到集合
        movement.setMedias(pathList);
        movement.setId( ObjectId.get() ); //自己赋值一个id 数据库就不会自己赋值了
        movement.setState( 0 );//TODO 审核状态 0 表示未审核 1表示已审核  开发阶段默认写死
        //3.调用保存
        movementService.saveMovement( movement );//出现空指针  指向到某一行  null.方法()
        rabbitTemplate.convertAndSend("tanhua.movement.state" ,movement.getId().toHexString() );

        //发动态保存得分
        mqMovementManager.sendMovementMQ(UserHolder.getUserId() ,movement.getId() , 1 );
        return null;
    }


    @DubboReference
    private UserInfoService userInfoService;
    //查询我的个人动态
    public ResponseEntity findMyMovement(Integer page, Integer pagesize, Long userId) {
        //1.调用服务器获得分页数据
        PageBeanVo pageBeanVo = movementService.findMyMovementByPage(userId, page, pagesize);

        //2.获得list数据
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        List<MovementVo> voList =new ArrayList<>();
        if(CollectionUtil.isNotEmpty(movementList)){
            for (Movement movement : movementList) {
                //2.1 在查询出 UserInfo数据
                UserInfo userInfo = userInfoService.findByUserId(movement.getUserId());
                //2.2 根据 Movement 和 UserInfo 构建  MovementVo 对象 (页面所需对象)
                MovementVo vo = new MovementVo();
                //userInfo的封装必须写在前面  movement封装必须写在后面  希望最后vo的id是 movement的id
                vo.setUserInfo( userInfo ); // 课前已经封装
                vo.setMovement( movement );// 课前已经封装
                voList.add(vo);
            }
        }
        //5.返回数据
        pageBeanVo.setItems(voList);  //重新覆盖分页的数据
        return ResponseEntity.ok(pageBeanVo);
    }

    //查询好友id
    public ResponseEntity findFriendMovement(Integer page, Integer pagesize) {
        //1.查询好友的动态
        PageBeanVo pageBeanVo = movementService.findFriendMovementByPage(UserHolder.getUserId(), page, pagesize);
        //2.封装PageBeanVo (参考我的动态)

        //2.获得list数据
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        List<MovementVo> voList =new ArrayList<>();
        if(CollectionUtil.isNotEmpty(movementList)){
            for (Movement movement : movementList) {
                //2.1 在查询出 UserInfo数据
                UserInfo userInfo = userInfoService.findByUserId(movement.getUserId());
                //2.2 根据 Movement 和 UserInfo 构建  MovementVo 对象 (页面所需对象)
                MovementVo vo = new MovementVo();
                //userInfo的封装必须写在前面  movement封装必须写在后面  希望最后vo的id是 movement的id
                vo.setUserInfo( userInfo ); // 课前已经封装
                vo.setMovement( movement );// 课前已经封装
                voList.add(vo);
            }
        }
        //5.返回数据
        pageBeanVo.setItems(voList);  //重新覆盖分页的数据
        return ResponseEntity.ok(pageBeanVo);
    }

    //查询推荐动态
    public ResponseEntity findRecommendMovement(Integer page, Integer pagesize) {
        //1.查询动态
        PageBeanVo pageBeanVo = movementService.findRecommendMovementByPage(UserHolder.getUserId(), page, pagesize);
        //2.获得list数据
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        List<MovementVo> voList =new ArrayList<>();
        if(CollectionUtil.isNotEmpty(movementList)){
            for (Movement movement : movementList) {
                //2.1 在查询出 UserInfo数据
                UserInfo userInfo = userInfoService.findByUserId(movement.getUserId());
                //2.2 根据 Movement 和 UserInfo 构建  MovementVo 对象 (页面所需对象)
                MovementVo vo = new MovementVo();
                //userInfo的封装必须写在前面  movement封装必须写在后面  希望最后vo的id是 movement的id
                vo.setUserInfo( userInfo ); // 课前已经封装
                vo.setMovement( movement );// 课前已经封装

                //是否点赞过
                String key = StrUtil.format(ConstantUtil.MOVEMENT_LIKE  , +UserHolder.getUserId() ,movement.getId().toHexString() );
                if(stringRedisTemplate.hasKey(key)){ //如果key存在 意味着点赞过
                    vo.setHasLiked(1); //点赞过
                }

                voList.add(vo);
            }
        }
        //5.返回数据
        pageBeanVo.setItems(voList);  //重新覆盖分页的数据
        return ResponseEntity.ok(pageBeanVo);
    }

    @DubboReference
    private CommentService commentService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //点赞 - 保存一条comment
    public ResponseEntity movementLike(String publishId) {
        //查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));

        //构建comment
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis()); //时间
        comment.setCommentType(  1 ); //点赞
        comment.setPublishId( new ObjectId(publishId)  ); //动态id
        comment.setPublishUserId( movement.getUserId() ); //发布动态人的id
        comment.setUserId( UserHolder.getUserId() );//操作人的id
        //保存comment
        Integer count = commentService.saveComment(comment);

        //记录一下点赞的状态  如果redis中含有这个key 表示点赞过
        //stringRedisTemplate.opsForValue().set( "dianzan_" +UserHolder.getUserId() + "_" + publishId  , "xxxx");
        String key = StrUtil.format(ConstantUtil.MOVEMENT_LIKE  , +UserHolder.getUserId() ,publishId );
        stringRedisTemplate.opsForValue().set( key  , "xxxx");


        //点赞保存得分
        mqMovementManager.sendMovementMQ(UserHolder.getUserId() ,movement.getId() , MQMovementManager.MOVEMENT_LIKE);
        return ResponseEntity.ok(count);
    }

    //取消点赞  - 删除一条comment
    public ResponseEntity movementDislike(String publishId) {
        //删除点赞
        Integer count = commentService.removeComment(UserHolder.getUserId(), new ObjectId(publishId), 1);//取消点赞

        //删除redis中的key 相当于删除点赞状态  如果redis中含有这个key 表示点赞过
        String key = StrUtil.format(ConstantUtil.MOVEMENT_LIKE  , +UserHolder.getUserId() ,publishId );
        stringRedisTemplate.delete(key);
        return ResponseEntity.ok(count);
    }

    //查询单条动态
    public ResponseEntity findMovementsById(String publishId) {
        //1.根据动态id查询动态的数据
        Movement movement = movementService.findById(new ObjectId(publishId));
        //2.根据动态的数据查询userInfo
        UserInfo userInfo = userInfoService.findByUserId(movement.getUserId());
        //3.封装vo
        MovementVo vo = new MovementVo();
        vo.setUserInfo( userInfo );
        vo.setMovement( movement );
        return ResponseEntity.ok(vo);
    }

    //评论列表
    public ResponseEntity findCommentsList(Integer page, Integer pagesize, String publishId) {
        //1.查询评论列表
        PageBeanVo pageBeanVo = commentService.findCommentByPage(new ObjectId(publishId), 2, page, pagesize);
        //2.查询userInfo
        List<Comment> commentList = (List<Comment>) pageBeanVo.getItems();
        List<CommentVo> voList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(commentList)){
            for (Comment comment : commentList) {
                //查询用户的基本数据
                UserInfo userInfo = userInfoService.findByUserId(comment.getUserId());
                //构建vo
                CommentVo vo = new CommentVo();
                BeanUtil.copyProperties( userInfo  , vo);
                BeanUtil.copyProperties( comment , vo);
                vo.setCreateDate(DateFormatUtil.format( new Date( comment.getCreated() ))); //完善时间

                voList.add( vo );
            }
        }
        //3.构建vo
        //4.返回
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    //保存评论
    public ResponseEntity saveComment(String publishId, String content) {
        //查询movement
        Movement movement = movementService.findById(new ObjectId(publishId));

        //构建Comment
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setCommentType(2);//评论
        comment.setPublishId(new ObjectId(publishId));//动态id
        comment.setPublishUserId( movement.getUserId() );//动态所属人id
        comment.setContent( content ); //内容
        comment.setUserId( UserHolder.getUserId() );//操作人id
        //保存
        Integer count = commentService.saveComment(comment);
        //返回
        return ResponseEntity.ok(count);
    }
}
